﻿using System;
using System.Collections.Generic;
using SMLib.Base;
using MBT.Modeling;

namespace MBT.TestStateLevel
{
	public class TestAutomaton :
        DiGraph<TA_State, TA_State.TA_Transition>
	{
		class TestTransitionInfo
		{
			public string label;
			public bool controllable;
			public bool final;
			public ActionInfo param;

			public TestTransitionInfo (string label, bool controllable, bool final, ActionInfo param)
			{
				this.param = param;
				this.controllable = controllable;
				this.label = label;
				this.final = final;
			}
		}
		
		public TA_State AddState (TA_State src, object dstObj, TA_State.TA_Transition tr)
		{
			TA_State dst = null;
			foreach (TA_State st in this.GetStates()) {
				if (st.state.Equals (dstObj)) {
					dst = st;
					break;
				}
			}
			if (dst == null) {
				dst = new TA_State ();
				dst.state = dstObj;
				this.states.Add (dst);
				dst.id = this.Size;
			}

			src.transitions.Add (tr);
			tr.Destination = dst;
			return dst;
		}

        #region Re-Write abstract methods
		protected TA_State newStateContainer (object content)
		{
			TA_State ts = new TA_State ();
			ts.id = Size + 1;
			ts.state = content;
			return ts;
		}

		protected TA_State.TA_Transition newTransition (TA_State st, object tr)
		{
			TestTransitionInfo inf = (TestTransitionInfo)tr;
			return new TA_State.TA_Transition (st, inf.label, inf.controllable, inf.param);
		}

		protected void UpdateTransition (TA_State src, TA_State.TA_Transition tr, object newTr)
		{
			//[To Do:]: add a new transition or what?
			TestTransitionInfo inf = (TestTransitionInfo)newTr;
			src.Transitions.Add (new TA_State.TA_Transition (tr.Destination, inf.label, inf.controllable, inf.param));
		}

		/*
        protected string TransitionLabel(ITransition tr)
        {
            string st = (((TA_State.Transition)tr).isControllable ? "?" : "!");
            st += ((TA_State.Transition)tr).actionName;
            st += ((TA_State.Transition)tr).parameters.ToString();
            return st;
        }
        */
        #endregion

		bool isDeadState (TA_State s)
		{
			return s.Transitions.Count == 0;
		}

		const int numberOfMutex = 2;

		public virtual TestAutomaton[] Find ()
		{
			return null;
		}

		public virtual void Initialize (object to)
		{
			TA_State mystate = new TA_State ();
			mystate.state = to;
			mystate.id = 1;
			AddState (mystate);
		}
        	
		public override TA_State DestinationOf (TA_State.TA_Transition t)
		{
			return t.Destination;
		}
	}
}
